package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.tanhua.autoconfig.exceptor.BusinessException;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.MovementApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VisitorsApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.MovementsVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.VisitorsVo;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class MovementsService {
    @Autowired
    private OssTemplate ossTemplate;

    @DubboReference
    private MovementApi movementApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private VisitorsApi visitorsApi;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /**
     * 发布动态
     * */
    public void publishMovement(Movement movement, MultipartFile[] imageComtent ) throws IOException {
        // 1判断发布动态的内容是否存在
        if (StringUtils.isEmpty(movement.getTextContent())){
            throw new BusinessException(ErrorResult.contentError());
        }

        // 2获取当前登陆的用户的id
        Long userId = UserHolder.getUserId();

        // 3将文件上传到阿里云oss 获取请求地址
        ArrayList<String> medias = new ArrayList<>();
        for (MultipartFile multipartFile : imageComtent) {
            String upload = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
            medias.add(upload);
        }
        // 4 将数据封装到movement 对象
        movement.setUserId(userId);
        movement.setMedias(medias);

        // 5 调用Api 完成发布动态
        movementApi.publish(movement);
    }


    //查询我的动态
    public PageResult findByUserId(Long userId, Integer page, Integer pagesize) {
        // 根据用户id 调用api 查询个人动态内容（PageResult Movement）
        PageResult pr = movementApi.findByUserId(userId,page,pagesize);

        // 获取PageResult 中的 item 列表对象
        List<Movement> items = (List<Movement>) pr.getItems();

        // 非空判断
        if (items == null){
            return pr;
        }

        // 循环数据列表
        UserInfo userInfo = userInfoApi.findById(userId);
        ArrayList<MovementsVo> vos = new ArrayList<>();
        for (Movement item : items) {
            // 一个Movement 构建一个Vo对象
            MovementsVo vo = MovementsVo.init(userInfo,item);
            vos.add(vo);
        }

        // 构建返回值
        pr.setItems(vos);
        return pr;
    }

    // 查询好友动态
    public PageResult findFriendMovements(Integer page, Integer pagesize) {

        //1： 获取当前用户id
        Long userId = UserHolder.getUserId();

        //2: 查询数据列表
        List<Movement> items = movementApi.findFriendMovements(userId,page,pagesize);

        //3: 非空判断
        if (CollUtil.isEmpty(items)){
            return new PageResult();
        }

        //4: 获取好友用户id
        List<Long> userIds = CollUtil.getFieldValues(items, "userId", Long.class);

        //5：循环数据列表
        Map<Long,UserInfo> userMaps  = userInfoApi.findByIds(userIds, null);
        ArrayList<MovementsVo> vos = new ArrayList<>();
        for (Movement item : items) {
            // 一个movement 构建一个vo对象
            UserInfo userInfo = userMaps.get(item.getUserId());
            MovementsVo vo = MovementsVo.init(userInfo, item);
            vos.add(vo);

        }

        //6:构建返回值
        return new PageResult(page,pagesize,0L,vos);
    }

    /**
     * 推荐动态
     * */
    public PageResult findRecommendMovements(Integer page, Integer pageseze) {
        //从redis从获取推荐动态id字符串 如果为空 则随机获取
        String redisKey = "MOVEMENTS_RECOMMEND_"+UserHolder.getUserId();
        String redisDate = this.redisTemplate.opsForValue().get(redisKey);

        List<Movement> list = Collections.EMPTY_LIST;
        if (StringUtils.isEmpty(redisDate)){
            list=movementApi.randomMovements(pageseze); //获取随机的动态集合
        }else {
            String[] split = redisDate.split(",");

            //如果起始索引 超过数组最大长度 则返回空 对象
            if ((page -1)* pageseze > split.length){
                return new PageResult();
            }

            //如果起始索引在数组范围内 将目标对象 放置进 集合中
            List<Long> pids = Arrays.stream(split)
                    .skip((page -1)*pageseze) //起始索引位置 、跳过前面所有元素
                    .limit(pageseze)
                    .map(e-> Convert.toLong(e))
                    .collect(Collectors.toList());

            //通过目标id集合查到 关联的动态集合
            list = movementApi.findByPids(pids);
        }
        //提取动态集合中的 userId 集合
        List<Long> userIds = CollUtil.getFieldValues(list,"userId",Long.class );

        // 循环 数据列表
        Map<Long,UserInfo> userMaps = userInfoApi.findByIds(userIds,null)   ;
        List<MovementsVo> vos = new ArrayList<>();

        // 遍历动态集合 结合用户详情 构建vo对象集合
        for (Movement item : list) {
            UserInfo userInfo = userMaps.get(item.getUserId());
            MovementsVo vo = MovementsVo.init(userInfo, item);
            vos .add(vo);
        }

        //构建返回值
        return new PageResult(page,pageseze,0L,vos) ;

    }

    /**
     * 根据id 查询动态
     * */
    public MovementsVo findMovementById(String movementId) {
        Movement movements = movementApi .findById(movementId);
        if (movements == null){
            return null;
        }else {
            UserInfo userInfo = userInfoApi.findById(movements.getUserId());
            return MovementsVo.init(userInfo,movements);
        }

    }

    /**
     * 谁看过我 访客列表
     * */
    public List<VisitorsVo> queryVisitorsList() {
        // 查询访问时间
        String key = Constants.VISITORS;
        String hashKey = String.valueOf(UserHolder.getUserId());
        String value = (String)redisTemplate.opsForHash().get(key,hashKey);
        Long date = StringUtils.isEmpty(value) ? null:Long.valueOf(value);

        // 调用api 查询数据列表
        List<Visitors> list = visitorsApi.queryMyVisitor(UserHolder.getUserId(),date);

        // 提取用户的id
        List<Long> userIds = CollUtil.getFieldValues(list,"visitorUserId",Long.class);

        // 查看用户的详情
        Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(userIds,null);
        // 构造返回
        ArrayList<VisitorsVo> visitorsVos = new ArrayList<>();

        for (Visitors visitors : list) {
            UserInfo userInfo = userInfoMap.get(visitors.getVisitorUserId());
            if (userInfo != null){
                VisitorsVo vo = VisitorsVo.init(userInfo, visitors);
                visitorsVos.add(vo);
            }
        }

        return visitorsVos;
    }
}
